/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/*******************************************************************************
    FILE NAME:		ecanlib.h

    PROJECT:		Linux ECAN527/1000 driver, library, and sample programs

    FILE DESCRIPTION:	This header file contains definitions for the user
    			level library functions.

    Copyright (c) 2004 RTD Embedded Technologies, Inc.

    For driver version, compiler, and target information, please refer to the
    file README.TXT.
*******************************************************************************/

#ifndef  _ECAN_LIB_H
# define _ECAN_LIB_H

# include <ecanioctl.h>
# include <errno.h>
# include <signal.h>
# include <sys/types.h>

# ifndef __cplusplus
#  error C++ compiler needed for this source
# endif


/******************************************************************************
 * Note that errno codes other than the ones indicated may be set by the      *
 * functions defined in this header file.  Please see the ioctl(2) man page   *
 * for more information.                                                      *
 ******************************************************************************/


/******************************************************************************
 * rtd_ecan_clear_accounts()                                                  *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Clear the statistics the driver keeps internally about device and     *
 *	driver operation.                                                     *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle => Device handle from Ecan_CreateHandle() or file descriptor   *
 *		  from open() system call.                                    *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 ******************************************************************************/

int rtd_ecan_clear_accounts(int handle);


/******************************************************************************
 * rtd_ecan_get_accounts()                                                    *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Get the statistics the driver keeps internally about device and       *
 *	driver operation.                                                     *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =======> Device handle from Ecan_CreateHandle() or file        *
 *			descriptor from open() system call.                   *
 *	statistics_p => Address of structure where statistics will be stored. *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EFAULT                                                            *
 *		statistics_p is not a valid user address.                     *
 ******************************************************************************/

int rtd_ecan_get_accounts(int handle, rtd_ecan_accounts_t *statistics_p);


/******************************************************************************
 * rtd_ecan_get_driver_version()                                              *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Get the driver version number.                                        *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle => Device handle from Ecan_CreateHandle() or file descriptor   *
 *		  from open() system call.                                    *
 *                                                                            *
 *  Return value:                                                             *
 *	On success, returns an integer driver version encoding the major,     *
 *	minor, and patch level version numbers.  The driver version is        *
 *	encoded using the formula                                             *
 *		driver version = (                                            *
 *			(MajorVersion << 16)                                  *
 *			|                                                     *
 *			(MinorVersion << 8)                                   *
 *			|                                                     *
 *			PatchLevel                                            *
 *		)                                                             *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 ******************************************************************************/

ssize_t rtd_ecan_get_driver_version(int handle);


/******************************************************************************
 * rtd_ecan_get_board_name()                                                  *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Get an ECAN board's type.                                             *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle => Device handle from Ecan_CreateHandle() or file descriptor   *
 *		  from open() system call.                                    *
 *                                                                            *
 *  Return value:                                                             *
 *	On success, returns an integer board type with 527 representing the   *
 *	ECAN527 and 1000 denoting the ECAN1000.                               *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 ******************************************************************************/

ssize_t rtd_ecan_get_board_name(int handle);


/******************************************************************************
 * rtd_ecan_set_bus_config()                                                  *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set CAN timing and bus configuration.  This function puts the board   *
 *	in reset mode, so you must start the board afterward.                 *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *	BusTiming0 => Device specific value for bus timing register 0.        *
 *	BusTiming1 => Device specific value for bus timing register 1.        *
 *	ClockOut ===> Device specific value for frequency divider at the      *
 *		      external CLKOUT pin relatively to the frequency of the  *
 *		      external oscillator.  A value of 0 means don't change.  *
 *	BusConfig ==> Device specific value for Output Control Register       *
 *		      (ECAN1000) or Bus Configuration Register (ECAN527).     *
 *		      A value of 0xFF means set the bus to the default        *
 *		      configuration.                                          *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EINVAL                                                            *
 *		Configuration value is not valid.                             *
 *	    EIO                                                               *
 *		The driver was unable to turn on the Reset Mode bit in the    *
 *		Mode Register to reconfigure the board (ECAN1000 only).       *
 ******************************************************************************/

int rtd_ecan_set_bus_config(
    int handle,
    u8_t BusTiming0,
    u8_t BusTiming1,
    u8_t ClockOut,
    u8_t BusConfig
);


/******************************************************************************
 * rtd_ecan_send_command()                                                    *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Send a command to an ECAN device.  ECAN1000 only.                     *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle ====> Device handle from Ecan_CreateHandle() or file           *
 *		     descriptor from open() system call.                      *
 *	command_p => Address of structure containing command to send.         *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EFAULT                                                            *
 *		command_p is not a valid user address.                        *
 *	    ENOTSUP                                                           *
 *		Operation is not supported (ECAN527 only).                    *
 ******************************************************************************/

int rtd_ecan_send_command(
    int handle,
    const struct rtd_ecan_send_command *command_p
);


/******************************************************************************
 * rtd_ecan_get_ram()                                                         *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Read CAN controller's RAM area into user buffer.                      *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *	ram_offset => Offset into board's RAM area.                           *
 *	ram_len ====> Number of bytes to read from RAM area.                  *
 *	buffer_p ===> Address of buffer in which to store the data read.      *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EFAULT                                                            *
 *		buffer_p is not a valid user address.                         *
 *		-OR-                                                          *
 *		The buffer is not big enough to store the data read.          *
 *	    EINVAL                                                            *
 *		ram_offset is outside the board's RAM area.                   *
 *		-OR-                                                          *
 *		ram_len is outside the board's RAM area.                      *
 *		-OR-                                                          *
 *		ram_offset plus ram_len is outside the board's RAM area.      *
 ******************************************************************************/

int rtd_ecan_get_ram(
    int handle,
    size_t ram_offset,
    size_t ram_len,
    void *buffer_p
);


/******************************************************************************
 * rtd_ecan_set_ram()                                                         *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Write into CAN controller's RAM area from user buffer.                *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *	ram_offset => Offset into board's RAM area.                           *
 *	ram_len ====> Number of bytes to write into RAM area.                 *
 *	buffer_p ===> Address of buffer which contains the data to write.     *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EFAULT                                                            *
 *		buffer_p is not a valid user address.                         *
 *		-OR-                                                          *
 *		More bytes are to be written than are in the buffer.          *
 *	    EINVAL                                                            *
 *		ram_offset is outside the board's RAM area.                   *
 *		-OR-                                                          *
 *		ram_len is outside the board's RAM area.                      *
 *		-OR-                                                          *
 *		ram_offset plus ram_len is outside the board's RAM area.      *
 ******************************************************************************/

int rtd_ecan_set_ram(
    int handle,
    size_t ram_offset,
    size_t ram_len,
    const void *buffer_p
);


/******************************************************************************
 * rtd_ecan_set_leds()                                                        *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Turn on or off an interface's LEDs.  ECAN527 only.                    *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle ===> Device handle from Ecan_CreateHandle() or file descriptor *
 *		    from open() system call.                                  *
 *	led_mask => Bit mask of LEDs to turn on.  If an LED bit is set is the *
 *		    mask, that LED will be turned on and if an LED bit is     *
 *		    cleared in the mask, that LED will be turned off.  Valid  *
 *		    bits are RTD_ECAN_LED_RED and RTD_ECAN_LED_GREEN.         *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EINVAL                                                            *
 *		led_mask contains an invalid LED bit.                         *
 *	    ENOTSUP                                                           *
 *		Operation is not supported (ECAN1000 only).                   *
 ******************************************************************************/

int rtd_ecan_set_leds(int handle, uint led_mask);


/******************************************************************************
 * rtd_ecan_set_rx_max_queue_size()                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set interface's receive queue size.  Doing so will also clear the     *
 *	the receive queue contents.                                           *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =========> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	max_queue_size => Size of receive queue in message items.             *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    ENOMEM                                                            *
 *		No memory available for given number of message items.        *
 ******************************************************************************/

int rtd_ecan_set_rx_max_queue_size(int handle, size_t max_queue_size);


/******************************************************************************
 * rtd_ecan_set_tx_max_queue_size()                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set interface's transmit queue size.  Doing so will also clear the    *
 *	the transmit queue contents.                                          *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =========> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	max_queue_size => Size of transmit queue in message items.            *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    ENOMEM                                                            *
 *		No memory available for given number of message items.        *
 ******************************************************************************/

int rtd_ecan_set_tx_max_queue_size(int handle, size_t max_queue_size);


/******************************************************************************
 * rtd_ecan_clear_queues()                                                    *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Clear the specified queue on an interface.                            *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *	queue_mask => Bit mask of queues to clear.  Valid bits are            *
 *		      RTD_ECAN_RX_QUEUE and RTD_ECAN_TX_QUEUE.                *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EINVAL                                                            *
 *		queue_mask contains an invalid bit.                           *
 ******************************************************************************/

int rtd_ecan_clear_queues(int handle, uint queue_mask);


/******************************************************************************
 * rtd_ecan_get_queues_counts()                                               *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Get the number of message items in an interface's receive and         *
 *	transmit queues.                                                      *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *	rx_count_p => Address where to store receive queue message count.     *
 *	tx_count_p => Address where to store transmit queue message count.    *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EFAULT                                                            *
 *		rx_count_p is not a valid user address.                       *
 *		-OR-                                                          *
 *		tx_count_p is not a valid user address.                       *
 ******************************************************************************/

int rtd_ecan_get_queues_counts(
    int handle,
    size_t *rx_count_p,
    size_t *tx_count_p
);


/******************************************************************************
 * rtd_ecan_stop()                                                            *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Put an interface into reset mode.                                     *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EIO                                                               *
 *		The driver was unable to turn on the Reset Mode bit in the    *
 *		Mode Register (ECAN1000 only).                                *
 ******************************************************************************/

int rtd_ecan_stop(int handle);


/******************************************************************************
 * rtd_ecan_start()                                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Put an interface into operating mode.                                 *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EIO                                                               *
 *		The driver was unable to turn on the Reset Mode bit in the    *
 *		Mode Register to reconfigure the board (ECAN1000 only).       *
 *                                                                            *
 *  NOTE:                                                                     *
 *	This function overwrites any filters you may have set.  You must set  *
 *	up your filters again after calling this function.                    *
 ******************************************************************************/

int rtd_ecan_start(int handle);


/******************************************************************************
 * rtd_ecan_test()                                                            *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Test an interface.  On the ECAN1000, this function also will clear    *
 *	the receive and transmit queue contents.                              *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EIO                                                               *
 *		The driver was unable to turn on the Reset Mode bit in the    *
 *		Mode Register (ECAN1000 only).                                *
 *		-OR-                                                          *
 *		The interface failed the test which writes indicator values   *
 *		into the 13 bytes of the Transmit Buffer, reads them back,    *
 *		and verifies values read match the values written (ECAN1000   *
 *		only).                                                        *
 *		-OR-                                                          *
 *		The interface failed the test which sets the Init bit in the  *
 *		Control Register and then reads it back in to verify it was   *
 *		set (ECAN527 only).                                           *
 *		-OR-                                                          *
 *		The interface failed the test which attempts to write to Bit  *
 *		Timing Register 1 while the Init bit in the Control Register  *
 *		is set but the Change Configuration Enable bit is cleared.    *
 *		When these Control Register bits are so set, a write to the   *
 *		Bit Timing Register 1 should not change its value.  In this   *
 *		case, it did (ECAN527 only).                                  *
 *		-OR-                                                          *
 *		The interface failed the test which attempts to write to Bit  *
 *		Timing Register 1 while the Init bit in the Control Register  *
 *		is set and the Change Configuration Enable bit is set.  When  *
 *		these Control Register bits are so set, a write to the Bit    *
 *		Timing Register 1 should change its value.  In this case, it  *
 *		did not (ECAN527 only).                                       *
 ******************************************************************************/

int rtd_ecan_test(int handle);


/******************************************************************************
 * rtd_ecan_prepare_received_message()                                        *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Prepare a received message for subsequent library calls, get the      *
 *	message's event mask, and get current receive queue size.  This       *
 *	function can operate either on the driver's receive queue or on the   *
 *	board directly.                                                       *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle ===========> Device handle from Ecan_CreateHandle() or file    *
 *			    descriptor from open() system call.               *
 *	events_p =========> Address where to store event flags.               *
 *	rx_queue_count_p => Address where to store receive queue count.       *
 *	dont_use_queue ===> Indicates whether or not to go directly to the    *
 *			    board for information.  0 means use the driver's  *
 *			    receive queue.  Any other value means go directly *
 *			    to the board.                                     *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EFAULT                                                            *
 *		events_p is not a valid user address.                         *
 *		-OR-                                                          *
 *		rx_queue_count_p is not a valid user address.                 *
 *	    EPERM                                                             *
 *		The Initialization bit is set in the Control Register and     *
 *		dont_use_queue is nonzero (ECAN527 only).                     *
 *                                                                            *
 * NOTE:                                                                      *
 *	If this function is used to operate on the receive queue, it will     *
 *	remove the first available message from that queue.  In addition,     *
 *	the queue count stored in the memory address referred to by           *
 *	rx_queue_count_p represents the number of entries remaining in the    *
 *	receive queue after removing the message.                             *
 ******************************************************************************/

int rtd_ecan_prepare_received_message(
    int handle,
    uint *events_p,
    size_t *rx_queue_count_p,
    int dont_use_queue
);


/******************************************************************************
 * rtd_ecan_get_status()                                                      *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Get status of current message.  This function can operate either on   *
 *	on the driver's receive queue or on the board directly.               *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =========> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	status_p =======> Address where to store status information           *
 *	dont_use_queue => Indicates whether or not to go directly to the      *
 *			  board for information.  0 means use the driver's    *
 *			  receive queue.  Any other value means go directly   *
 *			  to the board.                                       *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EFAULT                                                            *
 *		status_p is not a valid user address.                         *
 *	    EPERM                                                             *
 *		The Initialization bit is set in the Control Register and     *
 *		dont_use_queue is nonzero (ECAN527 only).                     *
 ******************************************************************************/

int rtd_ecan_get_status(
    int handle,
    struct rtd_ecan_status *status_p,
    int dont_use_queue
);


/******************************************************************************
 * rtd_ecan_set_events_mask()                                                 *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Tell an interface which events are of interest.  This function puts   *
 *	the board in reset mode, so you must start the board afterward.       *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle ======> Device handle from Ecan_CreateHandle() or file         *
 *		       descriptor from open() system call.                    *
 *	events_mask => Bit mask of desired events.  Valid bits are            *
 *		       RTD_ECAN_EVENT_RECEIVE, RTD_ECAN_EVENT_TRANSMIT,       *
 *		       RTD_ECAN_EVENT_ERROR_WARN_LIMIT,                       *
 *		       RTD_ECAN_EVENT_DATA_OVERRUN, RTD_ECAN_EVENT_WAKE_UP,   *
 *		       RTD_ECAN_EVENT_ERROR_PASSIVE,                          *
 *		       RTD_ECAN_EVENT_ARBITRATION_LOST,                       *
 *		       RTD_ECAN_EVENT_BUS_ERROR, and RTD_ECAN_EVENT_ALL.      *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EINVAL                                                            *
 *		events_mask contains an invalid bit.                          *
 *	    EIO                                                               *
 *		The driver was unable to turn on the Reset Mode bit in the    *
 *		Mode Register to reconfigure the board (ECAN1000 only).       *
 ******************************************************************************/

int rtd_ecan_set_events_mask(int handle, uint events_mask);


/******************************************************************************
 * rtd_ecan_recv_message()                                                    *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Retrieve a received message.  This function can operate either on the *
 *	driver's receive queue or on the board directly.                      *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =========> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	message_p ======> Address where to store the message.  On the         *
 *			  ECAN527, the Channel member of this structure can   *
 *			  be set to indicate which message object to retrieve *
 *			  if you want to go directly to the board.            *
 *	dont_use_queue => Indicates whether or not to go directly to the      *
 *			  board for a message.  0 means use the driver's      *
 *			  receive queue.  Any other value means go directly   *
 *			  to the board.                                       *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EBADSLT                                                           *
 *		The Channel member in the structure pointed to by message_p   *
 *		is zero and dont_use_queue is nonzero (ECAN527 only).         *
 *	    EFAULT                                                            *
 *		message_p is not a valid user address.                        *
 *	    EINVAL                                                            *
 *		The Channel member in the structure pointed to by message_p   *
 *		is not valid and dont_use_queue is nonzero (ECAN527 only).    *
 *	    EPERM                                                             *
 *		The Reset Mode bit is set in the Mode Register and            *
 *		dont_use_queue is nonzero (ECAN1000 only).                    *
 *		-OR-                                                          *
 *		The Initialization bit is set in the Control Register and     *
 *		dont_use_queue is nonzero (ECAN527 only).                     *
 ******************************************************************************/

int rtd_ecan_recv_message(
    int handle,
    struct rtd_ecan_message *message_p,
    int dont_use_queue
);


/******************************************************************************
 * rtd_ecan_send_message()                                                    *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Send a message.  This function can operate either on the driver's     *
 *	transmit queue or on the board directly.                              *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =========> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	message_p ======> Address where message is stored.                    *
 *	dont_use_queue => Indicates whether or not to go directly to the      *
 *			  board.  0 means use the driver's transmit queue.    *
 *			  Any other value means go directly to the board.     *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EBADSLT                                                           *
 *		The Channel member in the structure pointed to by message_p   *
 *		has the value 15 (ECAN527 only).                              *
 *	    EBUSY                                                             *
 *		The Transmission Buffer Status bit in the Control Register is *
 *		cleared and dont_use_queue is nonzero (ECAN1000 only).        *
 *	    EFAULT                                                            *
 *		message_p is not a valid user address.                        *
 *	    EINVAL                                                            *
 *		The Channel member in the structure pointed to by message_p   *
 *		is not valid (ECAN527 only).                                  *
 *	    ENOBUFS                                                           *
 *		dont_use_queue is 0 and there is no free slot in the driver's *
 *		transmit queue.                                               *
 *	    EPERM                                                             *
 *		The Reset Mode bit is set in the Mode Register and            *
 *		dont_use_queue is nonzero (ECAN1000 only).                    *
 *		-OR-                                                          *
 *		The Initialization bit is set in the Control Register and     *
 *		dont_use_queue is nonzero (ECAN527 only).                     *
 ******************************************************************************/

int rtd_ecan_send_message(
    int handle,
    struct rtd_ecan_message *message_p,
    int dont_use_queue
);


/******************************************************************************
 * rtd_ecan_setup_message_object()                                            *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set up a message object on an interface.  This function can instruct  *
 *	the driver to not process the transmit queue when a message object    *
 *	issues a Transmit Message Successfully interrupt.  ECAN527 only.      *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =========> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	object_p =======> Address of structure describing the object and how  *
 *			  to set it up.                                       *
 *	dont_use_queue => Indicates whether or not to process the transmit    *
 *			  queue when an Transmit Message Successfully         *
 *			  interrupt is generated by a message object.  A      *
 *			  value of 0 means process the transmit queue after   *
 *			  such an interrupt.  Any other value means do not    *
 *			  process the transmit queue after such an interrupt. *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    ECHNRG                                                            *
 *		The Channel member in the structure pointed to by object_p    *
 *		does not refer to a valid object.                             *
 *	    EFAULT                                                            *
 *		object_p is not a valid user address.                         *
 *	    EINVAL                                                            *
 *		The State member in the structure pointed to by object_p does *
 *		not contain a valid value.                                    *
 *		-OR-                                                          *
 *		In the structure pointed to by object_p, the Channel member   *
 *		has the value 15, the MakeDefault member is nonzero, and the  *
 *		State member is set to either RTD_ECAN_MO_TRANSMIT or         *
 *		RTD_ECAN_MO_REMOTE_TRANSMIT.                                  *
 *		-OR-                                                          *
 *		In the structure pointed to by object_p, the Channel member   *
 *		has the value 0 and the State member is set to                *
 *		RTD_ECAN_MO_DISABLED.                                         *
 *	    ENOTSUP                                                           *
 *		Operation is not supported (ECAN1000 only).                   *
 ******************************************************************************/

int rtd_ecan_setup_message_object(
    int handle,
    const struct rtd_ecan_msg_obj_setup *object_p,
    int dont_use_queue
);


/******************************************************************************
 * rtd_ecan_set_filter()                                                      *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set interface's message filter to mask out certain incoming messages. *
 *	This function can operate either on the driver's transmit queue or on *
 *	the board directly.  This function puts the board in reset mode, so   *
 *	you must start the board afterward.                                   *
 *                                                                            *
 *  Parameters:                                                               *
 *	handle =========> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	filter_p =======> Address of structure describing the filter and how  *
 *			  to set it up.                                       *
 *	dont_use_queue => Indicates whether or not to go directly to the      *
 *			  board.  0 means use the driver's transmit queue.    *
 *			  Any other value means go directly to the board.     *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		handle is not a valid file descriptor.                        *
 *	    EBUSY                                                             *
 *		dont_use_queue is nonzero and the Transmit Status or Receive  *
 *		Status bit is set in the Status Register (ECAN1000 only).     *
 *	    EFAULT                                                            *
 *		filter_p is not a valid user address.                         *
 *	    EIO                                                               *
 *		The driver was unable to turn on the Reset Mode bit in the    *
 *		Mode Register to reconfigure the board (ECAN1000 only).       *
 *	    ENOBUFS                                                           *
 *		dont_use_queue is 0 and there is no free slot in the driver's *
 *		transmit queue.                                               *
 *                                                                            *
 *  NOTE:                                                                     *
 *	On the ECAN527, this function no longer sets the message ID values in *
 *	the default standard and extended frame receive objects.  You must    *
 *	follow this function call with two calls to a function which will set *
 *	up those message objects.                                             *
 *                                                                            *
 *  NOTE:                                                                     *
 *	On the ECAN1000, do not use this function to set filters; the filter  *
 *	bits are set incorrectly in this case.  New functions have been added *
 *	to set filters on the ECAN1000.                                       *
 ******************************************************************************/

int rtd_ecan_set_filter(
    int handle,
    const struct rtd_ecan_filter *filter_p,
    int dont_use_queue
);


/******************************************************************************
 * rtd_ecan_read_digital_io()                                                 *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Read whatever value happens to be currently available on an           *
 *	interface's digital I/O port.  ECAN527 only.                          *
 *                                                                            *
 *  Parameters:                                                               *
 *	device_handle ==> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	digital_data_p => Address where to store the data read.               *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		device_handle is not a valid file descriptor.                 *
 *	    EFAULT                                                            *
 *		digital_data_p is not a valid user address.                   *
 *	    ENOTSUP                                                           *
 *		Operation is not supported (ECAN1000 only).                   *
 ******************************************************************************/

int rtd_ecan_read_digital_io(int device_handle, unsigned char *digital_data_p);


/******************************************************************************
 * rtd_ecan_write_digital_io()                                                *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Write a value to an interface's digital I/O port.  ECAN527 only.      *
 *                                                                            *
 *  Parameters:                                                               *
 *	device_handle ==> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	digital_data_p => Address where data to write is stored.              *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		device_handle is not a valid file descriptor.                 *
 *	    EFAULT                                                            *
 *		digital_data_p is not a valid user address.                   *
 *	    ENOTSUP                                                           *
 *		Operation is not supported (ECAN1000 only).                   *
 ******************************************************************************/

int rtd_ecan_write_digital_io(int device_handle, unsigned char *digital_data_p);


/******************************************************************************
 * rtd_ecan_load_port_bit_dir()                                               *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set direction (input or output) for each bit in an interface's        *
 *	digital I/O port.  ECAN527 only.                                      *
 *                                                                            *
 *  Parameters:                                                               *
 *	device_handle => Device handle from Ecan_CreateHandle() or file       *
 *			 descriptor from open() system call.                  *
 *	direction_p ===> Address of structure describing how to set bit       *
 *			 directions.                                          *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		device_handle is not a valid file descriptor.                 *
 *	    EFAULT                                                            *
 *		direction_p is not a valid user address.                      *
 *	    ENOTSUP                                                           *
 *		Operation is not supported (ECAN1000 only).                   *
 ******************************************************************************/

int rtd_ecan_load_port_bit_dir(
    int device_handle,
    const rtd_ecan_load_port_bit_dir_t *direction_p
);


/******************************************************************************
 * rtd_ecan_allow_buffer_overwrite()                                          *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Inform driver how to process receive queue overruns.                  *
 *                                                                            *
 *  Parameters:                                                               *
 *	device_handle => Device handle from Ecan_CreateHandle() or file       *
 *			 descriptor from open() system call.                  *
 *	allow =========> Flag to indicate receive queue overwrite status.  A  *
 *			 value of false means do not overwrite oldest queue   *
 *			 message when a new message arrives.  A value of true *
 *			 means overwrite the oldest queue message when a new  *
 *			 message arrives.                                     *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure with errno set as follows:                              *
 *	    EBADF                                                             *
 *		device_handle is not a valid file descriptor.                 *
 ******************************************************************************/

int rtd_ecan_allow_buffer_overwrite(int device_handle, unsigned char allow);


/******************************************************************************
 * Ecan_CreateHandle()                                                        *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Open an ECAN device so that other functions may be called for it.     *
 *                                                                            *
 *  Parameters:                                                               *
 *	DevNum ===> Board minor number.  The default value is 0.              *
 *	Ecan1000 => Selects board type.  The value false indicates that the   *
 *		    device is an ECAN527.  The value true indicates that the  *
 *		    device is an ECAN1000.  The default value is false.       *
 *                                                                            *
 *  Return value:                                                             *
 *	On success, returns the file descriptor of the file opened.           *
 *                                                                            *
 *	-1 on failure.  Please see the open(2) man page for information on    *
 *	possible values errno may have in this case.                          *
 ******************************************************************************/

HANDLE Ecan_CreateHandle(
    size_t DevNum = 0,
    bool Ecan1000 = false
);


/******************************************************************************
 * Ecan_GetBoardName()                                                        *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Get an ECAN board's type.                                             *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice => Device handle from Ecan_CreateHandle() or file descriptor  *
 *		   from open() system call.                                   *
 *                                                                            *
 *  Return value:                                                             *
 *	On success, returns an integer board type with 527 representing the   *
 *	ECAN527 and 1000 denoting the ECAN1000.                               *
 *                                                                            *
 *	0 on failure.  Please see the description of                          *
 *	rtd_ecan_get_board_name() for information on possible values errno    *
 *	may have in this case.                                                *
 ******************************************************************************/

ulong Ecan_GetBoardName(HANDLE hDevice);


/******************************************************************************
 * Ecan_BusConfig()                                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set CAN timing and bus configuration.  This function puts the board   *
 *	in reset mode, so you must start the board afterward.                 *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *	BusTiming0 => Device specific value for bus timing register 0.        *
 *	BusTiming1 => Device specific value for bus timing register 1.        *
 *	ClockOut ===> Device specific value for frequency divider at the      *
 *		      external CLKOUT pin relatively to the frequency of the  *
 *		      external oscillator.  A value of 0 means don't change.  *
 *		      The default value is 0.
 *	BusConfig ==> Device specific value for Output Control Register       *
 *		      (ECAN1000) or Bus Configuration Register (ECAN527).     *
 *		      A value of 0xFF means set the bus to the default        *
 *		      configuration.  The default value is 0xFF.              *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_set_bus_config() for information on possible values errno    *
 *	may have in this case.                                                *
 ******************************************************************************/

bool Ecan_BusConfig(
    HANDLE hDevice,
    u8_t BusTiming0,
    u8_t BusTiming1,
    u8_t ClockOut = 0,
    u8_t BusConfig = 0xff
);


/******************************************************************************
 * Ecan_SetupBoard()                                                          *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set an interface's event mask and default receive/transmit queue      *
 *	sizes.  This function puts the board in reset mode, so you must start *
 *	the board afterward.                                                  *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ==============> Device handle from Ecan_CreateHandle() or     *
 *				file descriptor from open() system call.      *
 *	ReceiveIntEn =========> Flag to indicate interest in Receive          *
 *				Interrupt.                                    *
 *	ErrorIntEn ===========> Flag to indicate interest in Error Warn       *
 *				Interrupt.                                    *
 *	TransmitIntEn ========> Flag to indicate interest in Transmit         *
 *				Interrupt.                                    *
 *	BusErrorIntEn ========> Flag to indicate interest in Bus Error        *
 *				Interrupt.                                    *
 *	DataOverrunIntEn =====> Flag to indicate interest in Data Overrun     *
 *				Interrupt.                                    *
 *	ArbitrationLostIntEn => Flag to indicate interest in Arbitration Lost *
 *				Interrupt.                                    *
 *	ErrorPassiveIntEn ====> Flag to indicate interest in Error Passive    *
 *				Interrupt.                                    *
 *	WakeUpIntEn ==========> Flag to indicate interest in Wake Up          *
 *				Interrupt.                                    *
 *	    A value of false for any of the above interrupt interest flags    *
 *	    indicates that the application is not interested in the           *
 *	    corresponding interrupt.  A value of true for any of the above    *
 *	    interrupt interest flags indicates that the application is        *
 *	    interested in the corresponding interrupt.  By default, only the  *
 *	    Receive Interrupt is of interest.                                 *
 *	RxSize ===============> Size of driver's receive queue.               *
 *	TxSize ===============> Size of driver's transmit queue.              *
 *	    A value of 0 for either of the above queue sizes indicates that   *
 *	    the corresponding queue size should not be changed.  The default  *
 *	    value for either queue size is 0.                                 *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_set_events_mask(), rtd_ecan_set_rx_max_queue_size(), and     *
 *	rtd_ecan_set_tx_max_queue_size() for information on possible values   *
 *	errno may have in this case.                                          *
 ******************************************************************************/

bool Ecan_SetupBoard(
    HANDLE hDevice,
    bool ReceiveIntEn = true ,
    bool ErrorIntEn = false,
    bool TransmitIntEn = false,
    bool BusErrorIntEn = false,
    bool DataOverrunIntEn = false,
    bool ArbitrationLostIntEn = false,
    bool ErrorPassiveIntEn = false,
    bool WakeUpIntEn = false,
    unsigned long int RxSize = 0,
    unsigned long int TxSize = 0
);


/******************************************************************************
 * Ecan_SendCommand()                                                         *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Send a command to an ECAN device.  ECAN1000 only.                     *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice => Device handle from Ecan_CreateHandle() or file descriptor  *
 *		   from open() system call.                                   *
 *	TR ======> Flag to send Transmission Request command.                 *
 *	RRB =====> Flag to send Release Receive Buffer command.               *
 *	AT ======> Flag to send Abort Transmission command.                   *
 *	CDO =====> Flag to send Clear Data Overrun command.                   *
 *	SRR =====> Flag to send Self Reception Request command.               *
 *	    A value of false for any of the above command flags indicates     *
 *	    that the corresponding command should not be sent.  A value of    *
 *	    true for any of the above command flags indicates that the        *
 *	    corresponding command should be sent.  By default, none of the    *
 *	    commands are sent.                                                *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_send_command() for information on possible values errno may  *
 *	have in this case.                                                    *
 ******************************************************************************/

bool Ecan_SendCommand(
    HANDLE hDevice,
    bool TR = false,
    bool RRB = false,
    bool AT = false,
    bool CDO = false,
    bool SRR = false
);


/******************************************************************************
 * Ecan_SetLeds()                                                             *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Turn on or off an interface's LEDs.  ECAN527 only.                    *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ==> Device handle from Ecan_CreateHandle() or file descriptor *
 *		    from open() system call.                                  *
 *	RedLed ===> Flag to turn on red LED.                                  *
 *	GreenLed => Flag to turn on green LED.                                *
 *	    A value of false for any of the above LED flags indicates that    *
 *	    the corresponding LED should be turned off.  A value of true for  *
 *	    any of the above LED flags indicates that the corresponding LED   *
 *	    should be turned on.                                              *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success or if rtd_ecan_set_leds() returned -1 and set errno   *
 *	to ENOTSUP.                                                           *
 *                                                                            *
 *	false on failure.  Please see the description of rtd_ecan_set_leds()  *
 *	for information on possible values errno may have in this case.       *
 ******************************************************************************/

bool Ecan_SetLeds(HANDLE hDevice, bool RedLed, bool GreenLed);


/******************************************************************************
 * Ecan_GetBuffer()                                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Read CAN controller's RAM area into user buffer.                      *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ======> Device handle from Ecan_CreateHandle() or file        *
 *			descriptor from open() system call.                   *
 *	StartAddress => Offset from beginning of RAM area.                    *
 *	Count ========> Number of bytes to read from RAM area.                *
 *	Buffer_p =====> Address of buffer in which to place RAM data.         *
 *	BuffSize =====> Size of buffer in bytes pointed to by Buffer_p.       *
 *                                                                            *
 *  Return value:                                                             *
 *	On success, returns the number of bytes read from board's RAM area.   *
 *                                                                            *
 *	0 on failure.  Please see the description of rtd_ecan_get_ram() for   *
 *	information on possible values errno may have in this case.           *
 ******************************************************************************/

size_t Ecan_GetBuffer(
    HANDLE hDevice,
    size_t StartAddress,
    size_t Count,
    void *Buffer_p,
    size_t BuffSize
);


/******************************************************************************
 * Ecan_SetBuffer()                                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Write into CAN controller's RAM area from user buffer.                *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ======> Device handle from Ecan_CreateHandle() or file        *
 *			descriptor from open() system call.                   *
 *	StartAddress => Offset from beginning of RAM area.                    *
 *	Count ========> Number of bytes to write into RAM area.               *
 *	Buffer_p =====> Address of buffer which contains data to write.       *
 *	BuffSize =====> Size of buffer in bytes pointed to by Buffer_p.       *
 *                                                                            *
 *  Return value:                                                             *
 *	On success, returns the number of bytes written to board's RAM area.  *
 *                                                                            *
 *	0 on failure.  Please see the description of rtd_ecan_set_ram() for   *
 *	information on possible values errno may have in this case.           *
 ******************************************************************************/

size_t Ecan_SetBuffer(
    HANDLE hDevice,
    size_t StartAddress,
    size_t Count,
    const void *Buffer_p,
    size_t BuffSize
);


/******************************************************************************
 * Ecan_StopBoard()                                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Put an interface into reset mode.                                     *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice => Device handle from Ecan_CreateHandle() or file descriptor  *
 *		   from open() system call.                                   *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of rtd_ecan_stop() for  *
 *	information on possible values errno may have in this case.           *
 ******************************************************************************/

bool Ecan_StopBoard(HANDLE hDevice);


/******************************************************************************
 * Ecan_StartBoard()                                                          *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Put an interface into operating mode.                                 *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice => Device handle from Ecan_CreateHandle() or file descriptor  *
 *		   from open() system call.                                   *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of rtd_ecan_start() for *
 *	information on possible values errno may have in this case.           *
 *                                                                            *
 *  NOTE:                                                                     *
 *	This function overwrites any filters you may have set.  You must set  *
 *	up your filters again after calling this function.                    *
 ******************************************************************************/

bool Ecan_StartBoard(HANDLE hDevice);


/******************************************************************************
 * Ecan_TestBoard()                                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Test an interface.  On the ECAN1000, this function also will clear    *
 *	the receive and transmit queue contents.                              *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice => Device handle from Ecan_CreateHandle() or file descriptor  *
 *		   from open() system call.                                   *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of rtd_ecan_test() for  *
 *	information on possible values errno may have in this case.           *
 ******************************************************************************/

bool Ecan_TestBoard(HANDLE hDevice);


/******************************************************************************
 * Ecan_GetQueuesCounts()                                                     *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Optionally get current driver receive and transmit queue message      *
 *	counts.  Optionally clear driver receive and transmit queues.         *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ====> Device handle from Ecan_CreateHandle() or file          *
 *		      descriptor from open() system call.                     *
 *	TX_Count_p => Address where to store the number of messages in the    *
 *		      driver's transmit queue.                                *
 *	RX_Count_p => Address where to store the number of messages in the    *
 *		      driver's receive queue.                                 *
 *	    A value of NULL for either address above indicates that the       *
 *	    corresponding values should not be returned.                      *
 *	ClearRX ====> Flag to indicate the receive queue should be cleared.   *
 *	ClearTX ====> Flag to indicate the transmit queue should be cleared.  *
 *	    A value of false for either flag above indicates that the         *
 *	    corresponding queue should not be cleared.  A value of true       *
 *	    indicates that the corresponding queue should be cleared.  The    *
 *	    default value for each flag is false.                             *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_clear_queues() and rtd_ecan_get_queues_counts() for          *
 *	information on possible values errno may have in this case.  In the   *
 *	case that rtd_ecan_get_queues_counts() fails, the memory pointed to   *
 *	by TX_Count_p and RX_Count_p is set to -1 if those values are to be   *
 *	returned.                                                             *
 ******************************************************************************/

bool Ecan_GetQueuesCounts(
    HANDLE hDevice,
    ulong *TX_Count_p,
    ulong *RX_Count_p,
    bool ClearRX = false,
    bool ClearTX = false
);


/******************************************************************************
 * Ecan_GetInterrupts()                                                       *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Prepare a received message for subsequent library calls.  This        *
 *	function can operate either on the driver's receive queue or on the   *
 *	board directly.                                                       *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ======> Device handle from Ecan_CreateHandle() or file        *
 *			descriptor from open() system call.                   *
 *	QueueSize_p ==> Address where to store number of messages in driver's *
 *			receive queue.  If this is NULL, do not return this   *
 *			information.  The default value is NULL.              *
 *	DontQueueUse => Flag to indicate going to the board.  A value of true *
 *			indicates going to the board.  A value of false means *
 *			use the driver's receive queue.  The default value is *
 *			false.
 *                                                                            *
 *  Return value:                                                             *
 *	On success, returns the mask of events pending.                       *
 *                                                                            *
 *	0 on failure.  Please see the description of                          *
 *	rtd_ecan_prepare_received_message() for information on possible       *
 *	values errno may have in this case.                                   *
 *                                                                            *
 * NOTE:                                                                      *
 *	If this function is used to operate on the receive queue, it will     *
 *	remove the first available message from that queue.  In addition,     *
 *	the queue count stored in the memory address referred to by           *
 *	QueueSize_p represents the number of entries remaining in the receive *
 *	queue after removing the message.                                     *
 ******************************************************************************/

uint Ecan_GetInterrupts(
    HANDLE hDevice,
    ulong *QueueSize_p = NULL,
    bool DontQueueUse = false
);


/******************************************************************************
 * Ecan_GetStatus()                                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Get status of current message.  This function can operate either on   *
 *	the driver's receive queue or on the board directly.                  *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ==> Device handle from Ecan_CreateHandle() or file descriptor *
 *		    from open() system call.                                  *
 *	status_p => Address of structure where status information should be   *
 *		    written.  The DontQueueUse member is used to indicate     *
 *		    whether or not the receive queue should be bypassed.  A   *
 *		    value of true in DontQueueUse means go to the board.  A   *
 *		    value of false in DontQueueUse means use the receive      *
 *		    queue.                                                    *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_get_status() for information on possible values errno may    *
 *	have in this case.                                                    *
 ******************************************************************************/

bool Ecan_GetStatus(HANDLE hDevice, ECAN_STATUS_STRUCTURE *status_p);


/******************************************************************************
 * Ecan_GetMessage()                                                          *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Retrieve a received message.  This function can operate either on the *
 *	driver's receive queue or on the board directly.                      *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ===> Device handle from Ecan_CreateHandle() or file           *
 *		     descriptor from open() system call.                      *
 *	message_p => Address of structure where message should be written.    *
 *		     The DontQueueUse member is used to indicate whether or   *
 *		     not the receive queue should be bypassed.  A value of    *
 *		     true in DontQueueUse means go to the board.  A value of  *
 *		     false in DontQueueUse means use the receive queue.       *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_recv_message() for information on possible values errno may  *
 *	have in this case.                                                    *
 ******************************************************************************/

bool Ecan_GetMessage (HANDLE hDevice, ECAN_MESSAGE_STRUCTURE *message_p);


/******************************************************************************
 * Ecan_SendMessage()                                                         *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Send a message.  This function can operate either on the driver's     *
 *	transmit queue or on the board directly.                              *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ===> Device handle from Ecan_CreateHandle() or file           *
 *		     descriptor from open() system call.                      *
 *	message_p => Address of structure where message is stored.  The       *
 *		     DontQueueUse member is used to indicate whether or not   *
 *		     the transmit queue should be bypassed.  A value of true  *
 *		     in DontQueueUse means go to the board.  A value of false *
 *		     in DontQueueUse means use the transmit queue.            *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_send_message() for information on possible values errno may  *
 *	have in this case.                                                    *
 ******************************************************************************/

bool Ecan_SendMessage(HANDLE hDevice, ECAN_MESSAGE_STRUCTURE *message_p);


/******************************************************************************
 * Ecan_MessageObjectSetup()                                                  *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set up a message object on an interface.  This function can instruct  *
 *	the driver to not process the transmit queue when a message object    *
 *	issues a Transmit Message Successfully interrupt.  ECAN527 only.      *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ==> Device handle from Ecan_CreateHandle() or file descriptor *
 *		    from open() system call.                                  *
 *	object_p => Address of structure where object initialization data is  *
 *		    stored.  The DontQueueUse member indicates whether or not *
 *		    to process the transmit queue when an Transmit Message    *
 *		    Successfully interrupt is generated by a message object.  *
 *		    A DontQueueUse value of 0 means process the transmit      *
 *		    queue after such an interrupt.  Any other DontQueueUse    *
 *		    value means do not process the transmit queue after such  *
 *		    an interrupt.                                             *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success or if rtd_ecan_setup_message_object() returned -1 and *
 *	set errno to ENOTSUP.                                                 *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_setup_message_object() for information on possible values    *
 *	errno may have in this case.                                          *
 ******************************************************************************/

bool Ecan_MessageObjectSetup(
    HANDLE hDevice,
    ECAN_MESSAGE_OBJECT_SETUP_STRUCTURE *object_p
);


/******************************************************************************
 * Ecan_SetFilter()                                                           *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Set interface's message filter to mask out certain incoming messages. *
 *	This function can operate either on the driver's transmit queue or on *
 *	the board directly.  This function puts the board in reset mode, so   *
 *	you must start the board afterward.                                   *
 *                                                                            *
 *  Parameters:                                                               *
 *	hDevice ==> Device handle from Ecan_CreateHandle() or file descriptor *
 *		    from open() system call.                                  *
 *	filter_p => Address of structure where filter data is stored.         *
 *                                                                            *
 *  Return value:                                                             *
 *	true on success.                                                      *
 *                                                                            *
 *	false on failure.  Please see the description of                      *
 *	rtd_ecan_set_filter() for information on possible values errno may    *
 *	have in this case.                                                    *
 *                                                                            *
 *  NOTE:                                                                     *
 *	On the ECAN527, this function no longer sets the message ID values in *
 *	the default standard and extended frame receive objects.  You must    *
 *	follow this function call with two calls to a function which will set *
 *	up those message objects.                                             *
 *                                                                            *
 *  NOTE:                                                                     *
 *	On the ECAN1000, do not use this function to set filters; the filter  *
 *	bits are set incorrectly in this case.  New functions have been added *
 *	to set filters on the ECAN1000.                                       *
 ******************************************************************************/

bool Ecan_SetFilter(HANDLE hDevice, const ECAN_FILTER_STRUCTURE *filter_p);


/******************************************************************************
 * Ecan_ReadDigitalIO()                                                       *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Read whatever value happens to be currently available on an           *
 *	interface's digital I/O port.  ECAN527 only.                          *
 *                                                                            *
 *  Parameters:                                                               *
 *	device_handle ==> Device handle Ecan_CreateHandle() or file           *
 *			  descriptor from open() system call.                 *
 *	digital_data_p => Address of user buffer in which to store data.      *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure.  Please see the description of                         *
 *	rtd_ecan_read_digital_io() for information on possible values errno   *
 *	may have in this case.                                                *
 ******************************************************************************/

int Ecan_ReadDigitalIO(HANDLE device_handle, unsigned char *digital_data_p);


/******************************************************************************
 * Ecan_WriteDigitalIO()                                                      *
 *                                                                            *
 *  Purpose:                                                                  *
 *      Write a value to an interface's digital I/O port.  ECAN527 only.      *
 *                                                                            *
 *  Parameters:                                                               *
 *	device_handle ==> Device handle Ecan_CreateHandle() or file           *
 *			  descriptor from open() system call.                 *
 *	digital_data_p => Address of user buffer containing data to write.    *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure.  Please see the description of                         *
 *	rtd_ecan_write_digital_io() for information on possible values errno  *
 *	may have in this case.                                                *
 ******************************************************************************/

int Ecan_WriteDigitalIO(HANDLE device_handle, unsigned char *digital_data_p);


/******************************************************************************
 * Ecan_LoadPortBitDir()                                                      *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Programs the direction (input or output) of each bit in the digital   *
 *	I/O port.                                                             *
 *                                                                            *
 *  Parameters:                                                               *
 *	device_handle ==> Device handle from Ecan_CreateHandle() or file      *
 *			  descriptor from open() system call.                 *
 *	bit7 ===========> Direction for bit 7.                                *
 *	bit6 ===========> Direction for bit 6.                                *
 *	bit5 ===========> Direction for bit 5.                                *
 *	bit4 ===========> Direction for bit 4.                                *
 *	bit3 ===========> Direction for bit 3.                                *
 *	bit2 ===========> Direction for bit 2.                                *
 *	bit1 ===========> Direction for bit 1.                                *
 *	bit0 ===========> Direction for bit 0.                                *
 *	    For bit7 through bit0, a value of false (0) means input and a     *
 *	    value of true (1) means output.  By default, each bit is set to   *
 *	    input.                                                            *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure.  Please see the description of                         *
 *	rtd_ecan_load_port_bit_dir() for information on possible values errno *
 *	may have in this case.                                                *
 ******************************************************************************/

int Ecan_LoadPortBitDir(
    HANDLE device_handle,
    bool bit7 = false,
    bool bit6 = false,
    bool bit5 = false,
    bool bit4 = false,
    bool bit3 = false,
    bool bit2 = false,
    bool bit1 = false,
    bool bit0 = false
);


/******************************************************************************
 * Ecan_AllowBufferOverwrite()                                                *
 *                                                                            *
 *  Purpose:                                                                  *
 *	Inform driver how to process receive queue overruns.                  *
 *                                                                            *
 *  Parameters:                                                               *
 *	device_handle => Device handle from Ecan_CreateHandle() or file       *
 *			 descriptor from open() system call.                  *
 *	allow =========> Flag to indicate whether or not to overwrite receive *
 *			 queue contents on overrun.  A value of false means   *
 *			 do not overwrite the oldest queue message with a new *
 *			 message and instead try to put an special overrun    *
 *			 message in the queue. A value of true means          *
 *			 overwrite the oldest queue message with a new        *
 *			 message and do not put a special overrun message in  *
 *			 the queue.                                           *
 *                                                                            *
 *  Return value:                                                             *
 *	0 on success.                                                         *
 *                                                                            *
 *	-1 on failure.  Please see the description of                         *
 *	rtd_ecan_allow_buffer_overwrite() for information on possible values  *
 *	errno may have in this case.                                          *
 ******************************************************************************/

int Ecan_AllowBufferOverwrite(HANDLE device_handle, bool allow);


/******************************************************************************
Ecan_SetBitRate()

    Purpose:
        Set CAN bus bit rate.

    Parameters:
        BitRate => CAN bus bit rate to set.  For a list of valid values,
                   please see the BitRates enumeration in include/ecanioctl.h.

    Return Value:
        true
            Success.

        false
            Failure with errno set as follows:
                EINVAL
                   BitRate is not valid.

            Please see the description of Ecan_BusConfig() for information on
            other possible values errno may have in this case.
 ******************************************************************************/

bool Ecan_SetBitRate(HANDLE device_handle, BitRates BitRate);


/******************************************************************************
Ecan_SetSingleFilterStandard()

    Purpose:
        For the ECAN1000 only, set up a filter for standard frames in single
        filter mode.

    Parameters:
        device_handle => Device handle from Ecan_CreateHandle() or file
                         descriptor from open() system call.
        ID_ACR ========> 11-bit Acceptance Code for message ID.
        ID_AMR ========> 11-bit Acceptance Mask for message ID.
        RTR_ACR =======> 1-bit Acceptance Code for Remote Transmission Request
                         bit.
        RTR_AMR =======> 1-bit Acceptance Mask for Remote Transmission Request
                         bit.
        Data_ACR ======> 16-bit Acceptance Code for first 16 bits of message
                         data.
        Data_AMR ======> 16-bit Acceptance Mask for first 16 bits of message
                         data.

    Return Value:
        true
            Filter set succeeded.

        false
            Filter set failed.  Please see the description of Ecan_SetFilter()
            for information on possible values errno may have in this case.

    NOTE:
        Unless you feel adventurous enough to undertake determining the exact
        bit patterns to set in the filter structure, do not use
        Ecan_SetFilter() or rtd_ecan_set_filter() to set filters on the
        ECAN1000.  Use this function instead.
 ******************************************************************************/

bool Ecan_SetSingleFilterStandard(
    HANDLE device_handle,
    uint ID_ACR,
    uint ID_AMR,
    uint RTR_ACR,
    uint RTR_AMR,
    uint Data_ACR,
    uint Data_AMR
);


/******************************************************************************
Ecan_SetSingleFilterExtended()

    Purpose:
        For the ECAN1000 only, set up a filter for extended frames in single
        filter mode.

    Parameters:
        device_handle => Device handle from Ecan_CreateHandle() or file
                         descriptor from open() system call.
        ID_ACR ========> 29-bit Acceptance Code for message ID.
        ID_AMR ========> 29-bit Acceptance Mask for message ID.
        RTR_ACR =======> 1-bit Acceptance Code for Remote Transmission Request
                         bit.
        RTR_AMR =======> 1-bit Acceptance Mask for Remote Transmission Request
                         bit.

    Return Value:
        true
            Filter set succeeded.

        false
            Filter set failed.  Please see the description of Ecan_SetFilter()
            for information on possible values errno may have in this case.

    NOTE:
        Unless you feel adventurous enough to undertake determining the exact
        bit patterns to set in the filter structure, do not use
        Ecan_SetFilter() or rtd_ecan_set_filter() to set filters on the
        ECAN1000.  Use this function instead.
 ******************************************************************************/

bool Ecan_SetSingleFilterExtended(
    HANDLE device_handle,
    uint ID_ACR,
    uint ID_AMR,
    uint RTR_ACR,
    uint RTR_AMR
);


/******************************************************************************
Ecan_SetDualFilterStandard()

    Purpose:
        For the ECAN1000 only, set up a filter for standard frames in dual
        filter mode.

    Parameters:
        device_handle => Device handle from Ecan_CreateHandle() or file
                         descriptor from open() system call.
        ID_ACR1 =======> 11-bit Acceptance Code 1 for message ID.
        ID_AMR1 =======> 11-bit Acceptance Mask 1 for message ID.
        ID_ACR2 =======> 11-bit Acceptance Code 2 for message ID.
        ID_AMR2 =======> 11-bit Acceptance Mask 2 for message ID.
        RTR_ACR1 ======> 1-bit Acceptance Code 1 for Remote Transmission
                         Request bit.
        RTR_AMR1 ======> 1-bit Acceptance Mask 1 for Remote Transmission
                         Request bit.
        RTR_ACR2 ======> 1-bit Acceptance Code 2 for Remote Transmission
                         Request bit.
        RTR_AMR2 ======> 1-bit Acceptance Mask 2 for Remote Transmission
                         Request bit.
        Data_ACR ======> 8-bit Acceptance Code for first 8 bits of message
                         data.
        Data_AMR ======> 8-bit Acceptance Mask for first 8 bits of message
                         data.

    Return Value:
        true
            Filter set succeeded.

        false
            Filter set failed.  Please see the description of Ecan_SetFilter()
            for information on possible values errno may have in this case.

    NOTE:
        Unless you feel adventurous enough to undertake determining the exact
        bit patterns to set in the filter structure, do not use
        Ecan_SetFilter() or rtd_ecan_set_filter() to set filters on the
        ECAN1000.  Use this function instead.
 ******************************************************************************/

bool Ecan_SetDualFilterStandard(
    HANDLE device_handle,
    uint ID_ACR1,
    uint ID_AMR1,
    uint ID_ACR2,
    uint ID_AMR2,
    uint RTR_ACR1,
    uint RTR_AMR1,
    uint RTR_ACR2,
    uint RTR_AMR2,
    uint Data_ACR,
    uint Data_AMR
);


/******************************************************************************
Ecan_SetDualFilterExtended()

    Purpose:
        For the ECAN1000 only, set up a filter for extended frames in dual
        filter mode.

    Parameters:
        device_handle => Device handle from Ecan_CreateHandle() or file
                         descriptor from open() system call.
        ID_ACR1 =======> 16-bit Acceptance Code 1 for message ID.
        ID_AMR1 =======> 16-bit Acceptance Mask 1 for message ID.
        ID_ACR2 =======> 16-bit Acceptance Code 2 for message ID.
        ID_AMR2 =======> 16-bit Acceptance Mask 2 for message ID.

    Return Value:
        true
            Filter set succeeded.

        false
            Filter set failed.  Please see the description of Ecan_SetFilter()
            for information on possible values errno may have in this case.

    NOTE:
        Unless you feel adventurous enough to undertake determining the exact
        bit patterns to set in the filter structure, do not use
        Ecan_SetFilter() or rtd_ecan_set_filter() to set filters on the
        ECAN1000.  Use this function instead.
 ******************************************************************************/

bool Ecan_SetDualFilterExtended(
    HANDLE device_handle,
    uint ID_ACR1,
    uint ID_AMR1,
    uint ID_ACR2,
    uint ID_AMR2
);


#endif /* _ECAN_LIB_H */
